/*
 * openMorph.h
 *
 *  Created: 20250804
 *  Author: Hecate
 */
#ifndef OPENMORPH_H
#define OPENMORPH_H

#include <stdint.h>

// 8 位图像句柄
typedef struct CroppedImage8 CroppedImage8;
// 16 位图像句柄
typedef struct CroppedImage16 CroppedImage16;

// 二值背景色
#define BLACK 0
// 二值前景色
#define WHITE 255
// 颜色翻转宏
#define cReverse(x) ((x) ? BLACK : WHITE)

// 初始化 8 位图像
CroppedImage8* CroppedImage8Init(uint8_t* data, uint16_t width, uint16_t height);
// 初始化 16 位图像
CroppedImage16* CroppedImage16Init(uint16_t* data, uint16_t width, uint16_t height);

// 获取 8 位图像数据指针
uint8_t* CroppedImage8GetImgPtr(const CroppedImage8* img);
// 获取 8 位图像宽度
uint16_t CroppedImage8GetImgWidth(const CroppedImage8* img);
// 获取 8 位图像高度
uint16_t CroppedImage8GetImgHeight(const CroppedImage8* img);

// 获取 16 位图像数据指针
uint16_t* CroppedImage16GetDataPtr(const CroppedImage16* img);
// 获取 16 位图像宽度
uint16_t CroppedImage16GetImgWidth(const CroppedImage16* img);
// 获取 16 位图像高度
uint16_t CroppedImage16GetImgHeight(const CroppedImage16* img);

// 腐蚀操作
void morphErode(const CroppedImage8* src, const CroppedImage8* kernel, CroppedImage8* dst, uint8_t background);

// 膨胀操作
void morphDilate(const CroppedImage8* src, const CroppedImage8* kernel, CroppedImage8* dst, uint8_t background);

// 开运算
void morphOpen(const CroppedImage8* src, const CroppedImage8* kernel, CroppedImage8* dst, uint8_t background);

// 闭运算
void morphClose(const CroppedImage8* src, const CroppedImage8* kernel, CroppedImage8* dst, uint8_t background);

// 单阈值二值化
void toBinary(const CroppedImage8* src, CroppedImage8* dst, uint8_t threshold);

// 双阈值二值化
void toBinaryDoubleThreshold(const CroppedImage8* src, CroppedImage8* dst, uint8_t thresholdUp, uint8_t thresholdDown);

// RGB565 转二值
void rgb565toBinary(const CroppedImage16* src, CroppedImage8* dst, uint8_t background, uint8_t r_min, uint8_t r_max, uint8_t g_min, uint8_t g_max, uint8_t b_min, uint8_t b_max);

typedef struct
{
    uint32_t beaX;     // 质心 X
    uint32_t beaY;     // 质心 Y
    uint16_t beaArea;  // 区域面积
} SBEA;

typedef struct
{
    uint8_t background;                  // 背景色值
    CroppedImage8* data;                 // 输入图像
    CroppedImage8* show;                 // 标注图像
    float areaTopMin;                    // 顶部最小面积
    float areaTopMax;                    // 顶部最大面积
    float kMin;                          // 面积下限斜率
    float kMax;                          // 面积上限斜率
    uint16_t xRange[2];                  // X 有效范围
    uint16_t yRange[2];                  // Y 有效范围
    uint16_t beaCount;                   // 有效区域数量
    uint8_t lastFrameBeaExist;           // 上帧是否存在
    uint32_t lastFrameSelectedBeaXY[2];  // 上帧选中坐标
    uint16_t selectedIndex;              // 当前选中索引
    SBEA sbea[101];                      // 区域缓存
} BEAINF;

// 初始化连通域检测器
void twoPassConnectedAreaInit(BEAINF* obj, uint8_t background, CroppedImage8* src, CroppedImage8* sho, float areaMinLow, float areaMaxLow, float areaMinHigh, float areaMaxHigh, float leftDeadZone, float rightDeadZone, float topDeadZone, float bottomDeadZone);

// 四邻域连通域处理
void twoPassFourConnectedAreaProcess(BEAINF* obj);

// 八邻域连通域处理
void twoPassEightConnectedAreaProcess(BEAINF* obj);

#endif  // OPENMORPH_H
